using AutoMapper;
using Matrix.ServiceDiscovery.Contracts.Dtos;
using Matrix.ServiceDiscovery.Entities;

namespace Matrix.ServiceDiscovery
{
    /// <summary>
    /// 服务发现AutoMapper配置
    /// </summary>
    public class ServiceDiscoveryAutoMapperProfile : Profile
    {
        public ServiceDiscoveryAutoMapperProfile()
        {
            // 实体到DTO的映射
            CreateMap<ServiceInfo, ServiceInfoDto>()
                .ForMember(dest => dest.HealthyInstanceCount, opt => opt.Ignore())
                .ForMember(dest => dest.TotalInstanceCount, opt => opt.Ignore());

            CreateMap<ServiceInstance, ServiceInstanceDto>()
                .ForMember(dest => dest.ServiceName, opt => opt.MapFrom(src => src.ServiceInfo != null ? src.ServiceInfo.Name : ""))
                .ForMember(dest => dest.ServiceVersion, opt => opt.MapFrom(src => src.ServiceInfo != null ? src.ServiceInfo.Version : ""))
                .ForMember(dest => dest.LoadBalancingStrategy, opt => opt.MapFrom(src => src.ServiceInfo?.LoadBalancingConfig != null ? src.ServiceInfo.LoadBalancingConfig.Strategy : LoadBalancingStrategy.RoundRobin));

            CreateMap<LoadBalancingConfig, LoadBalancingConfigDto>();

            // DTO到实体的映射（通常不需要完整的反向映射，因为创建操作使用构造函数和业务方法）
            CreateMap<CreateServiceDto, ServiceInfo>()
                .ConstructUsing(src => new ServiceInfo(
                    System.Guid.NewGuid(),
                    src.ServiceName,
                    src.ServiceVersion,
                    src.Description))
                .ForAllMembers(opts => opts.Ignore()); // 忽略所有成员，使用业务方法设置属性

            CreateMap<RegisterServiceInstanceDto, ServiceInstance>()
                .ConstructUsing(src => new ServiceInstance(
                    System.Guid.NewGuid(),
                    null, // TenantId will be set by service
                    src.ServiceName,
                    src.InstanceId,
                    src.Host,
                    src.Port,
                    src.Protocol))
                .ForAllMembers(opts => opts.Ignore());

            CreateMap<UpdateInstanceHealthDto, ServiceInstance>()
                .ForAllMembers(opts => opts.Ignore());

            CreateMap<HeartbeatDto, ServiceInstance>()
                .ForAllMembers(opts => opts.Ignore());

            CreateMap<UpdateLoadBalancingConfigDto, LoadBalancingConfig>()
                .ConstructUsing(src => new LoadBalancingConfig(System.Guid.Empty)) // ServiceId will be set by service
                .ForAllMembers(opts => opts.Ignore());

            // 输入DTO的映射（用于查询）
            CreateMap<GetServiceListInput, GetServiceListInputDto>()
                .ForMember(dest => dest.Keyword, opt => opt.MapFrom(src => src.Keyword))
                .ForMember(dest => dest.Category, opt => opt.MapFrom(src => src.Category))
                .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.Status))
                .ForMember(dest => dest.SkipCount, opt => opt.MapFrom(src => src.SkipCount))
                .ForMember(dest => dest.MaxResultCount, opt => opt.MapFrom(src => src.MaxResultCount));

            // 统计信息映射
            CreateMap<ServiceInfo, ServiceStatisticsDto>()
                .ForMember(dest => dest.ServiceName, opt => opt.MapFrom(src => src.Name))
                .ForMember(dest => dest.ServiceVersion, opt => opt.MapFrom(src => src.Version))
                .ForMember(dest => dest.TotalInstances, opt => opt.Ignore())
                .ForMember(dest => dest.HealthyInstances, opt => opt.Ignore())
                .ForMember(dest => dest.UnhealthyInstances, opt => opt.Ignore())
                .ForMember(dest => dest.UnknownInstances, opt => opt.Ignore())
                .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.Status))
                .ForMember(dest => dest.LastUpdated, opt => opt.MapFrom(src => src.LastModificationTime));

            // 特殊映射方法
            CreateMap<RegisterServiceDto, ServiceInfoDto>()
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.CreationTime, opt => opt.Ignore())
                .ForMember(dest => dest.LastModificationTime, opt => opt.Ignore());

            CreateMap<RegisterServiceInstanceDto, ServiceInstanceDto>()
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.CreationTime, opt => opt.Ignore())
                .ForMember(dest => dest.LastModificationTime, opt => opt.Ignore())
                .ForMember(dest => dest.LastHeartbeat, opt => opt.Ignore())
                .ForMember(dest => dest.HealthStatus, opt => opt.MapFrom(src => HealthStatus.Healthy));
        }
    }
}